package cn.codergege.gradle.plugin.kotlin

import cn.codergege.gradle.plugin.generateSourceCode
import org.gradle.api.tasks.TaskAction

open class KtBootWebThymeleafStage: KtBootWebBasicStage() {
    // 前端 version
    val jqueryVersion = "3.3.1-1"
    val faVersion = "5.0.10" // 基本上换版本的话, 整语句要换
    val bootstrapVersion = "4.1.0"
    val bpVersion = "6.0.1"
    val modernizrVersion = "3.5.0" // bp 里面的 modernizr

    @TaskAction
    override fun run() {
        super.run()
        // cn.codergege.demo.config.conversion.DateFormatter
        generateSourceCode(mainKtDir, conversionPackageDir, dateFormatterFileName, codeDateFormatter)
        // cn.codergege.demo.config.MyLocaleResolver
        generateSourceCode(mainKtDir, configPackageDir, myLocaleResolverFileName, codeMyLocaleResolver)
        // cn.codergege.demo.config.WebConfig
        generateSourceCode(mainKtDir, configPackageDir, webConfigFileName, codeWebConfig)
        // cn.codergege.demo.controller.ThymeleafController
        generateSourceCode(mainKtDir, controllerPackageDir, thymeleafControllerFileName, codeThymeleafController)
        // tag::resources
        // static/assets/css, img, js
        generateSourceCode(mainResourceDir, cssDir, appCss, codeAppCss)
        generateSourceCode(mainResourceDir, imgDir, imgGitignore, codeImgGitignore)
        generateSourceCode(mainResourceDir, jsDir, appJs, codeAppJs)
        // templates/thymeleaf/demo.html
        generateSourceCode(mainResourceDir, thymeleafDir, thymeleafDemoHtml, codeThymeleafDemoHtml)
        // templates/fragment.html, templates/fragment.html
        generateSourceCode(mainResourceDir, templatesDir, fragmentHtml, codeFragmentHtml)
        generateSourceCode(mainResourceDir, templatesDir, indexHtml, codeIndexHtml)
        // messages.properties
        generateSourceCode(mainResourceDir, "", messagesFileName, codeMessages)
        generateSourceCode(mainResourceDir, "", messagesUsFileName, codeMessagesUs)
        generateSourceCode(mainResourceDir, "", messagesCnFileName, codeMessagesCn)
        // end::resources
    }

    override var readmeMd = """# ${project.name} #

## Quik Start ##

```bash
gradle test
gradle
```
localhost:8888/
localhost:8888/index.html
localhost:8888/hello
localhost:8888/hi
localhost:8888/druid

## 使用的技术 ##

* Kotlin
* Spring Boot
    + web
    + data-jpa
    + thymeleaf
* 数据库(单数据源)
    + jpa
    + mysql, H2
    + druid
    + querydsl
* 前端
    + thymeleaf
    + jquery ${jqueryVersion}
    + bootstrap ${bootstrapVersion}
    + html5-boilerplate ${bpVersion}
* Test
    + spring boot test
    + Junit5

## Stage 插件 ##

使用 ktBootWebBasic 生成项目
`gradle ktBootWebThymeleaf`

## 修改为 Oracle 数据库 ##

* 新建 lib 目录, 复制 ojdbc6.jar 到 lib, 刷新 gradle
* 修改 yml 配置文件, 主要需要修改以下内容
```yaml
url: jdbc:oracle:thin:@10.22.10.120:1521:orcl
username: base
password: base
driver-class-name: oracle.jdbc.OracleDriver
...
jpa:
    database: ORACLE
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.Oracle9iDialect
    hibernate:
      ddl-auto: update
      naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
```

## Todo ##

>  TODO: 验证?
>  TODO: 错误处理
>  TODO: 文件上传下载
"""
    // messages.properties
    var messagesFileName = "messages.properties"
    var messagesUsFileName = "messages_en_US.properties"
    var messagesCnFileName = "messages_zh_CN.properties"
    var codeMessages = """index.welcome=欢迎使用 ${project.name}
date.format=yyyy-MM~dd
"""
    var codeMessagesUs = """index.welcome=Welcome to <b>${project.name}</b>
date.format=MM/dd/yyyy
"""
    var codeMessagesCn = """index.welcome=欢迎使用 ${project.name}
date.format=yyyy-MM-dd
"""
    var templatesDir = "templates"
    var staticDir = "static"
    var assetsDir = "$staticDir/assets"
    var cssDir = "$assetsDir/css"
    var imgDir = "$assetsDir/img"
    var jsDir = "$assetsDir/js"
    var appCss = "app.css"
    var imgGitignore = ".gitignore"
    var appJs = "app.js"
    var codeAppCss = """/* app.css */"""
    var codeImgGitignore = """"""
    var codeAppJs = """/**
* app.js
*/
${'$'}(function() {
//    console.log("test")
})
"""
    // templates/fragment.html, templates/fragment.html
    var fragmentHtml = "fragment.html"
    var indexHtml = "index.html"
    var codeFragmentHtml = """<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!-- Head 标签模板 -->
<head th:fragment="common_head(meta,title,link,style,script)">
    <!--/* Per-page placeholder for additional metas */-->
    <th:block th:replace="${'$'}{meta}"/>
    <title th:replace="${'$'}{title}">The awesome application</title>

    <!-- Common styles and scripts -->
    <!--<link rel="stylesheet" type="text/css" media="all" th:href="@{/assets/css/base.css}">-->
    <!--<script type="text/javascript" th:src="@{/assets/ext/jquery-3.2.1-min.js}"></script>-->
    <!--<script type="text/javascript" th:src="@{/assets/js/codergege.js}"></script>-->

    <!--/* Per-page placeholder for additional links */-->
    <th:block th:replace="${'$'}{link}"/>
    <!--/* Per-page placeholder for additional style */-->
    <th:block th:replace="${'$'}{style}"/>
    <!--/* Per-page placeholder for additional scripts */-->
    <th:block th:replace="${'$'}{script}"/>
</head>
<body>
<th:block th:fragment="browser">
<!--[if lt IE 8]>
<H1 class="browserupgrade text-warning">
    你使用的浏览器 <strong>版本太低了</strong>! . 为了最佳视觉体验, 快去
    这里<a href="http://browsehappy.com/">下载最新版本的浏览器</a>吧!
</H1>
<![endif]-->
</th:block>
<header th:fragment="header" class="container">
    <div class="row">
        <div class="col-md-1">
            <a class="btn btn-primary" th:href="@{/}">首页</a>
        </div>
    </div>
</header>
<footer th:fragment="footer" class="container bg-dark text-center">
    <div class="row">
        <div class="col-md-12 text-warning">
            Copyright &copy; 赵波
        </div>
    </div>
    <div class="row">
        <div class="col-md-12 text-danger">
            Email: codergege@163.com
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <p>
                <a id="zhcn" class="btn btn-sm" href="">中文</a>
                <a id="enus" class="btn btn-sm" href="">English</a>
            </p>
        </div>
    </div>
</footer>
<th:block th:fragment="scriptlib">
<!--这里可以放公共 js 库-->
<!--中英文切换 js-->
<script>
    var pageUrl = window.location.pathname
    ${'$'}("#zhcn").attr("href",pageUrl + "?l=zh_CN")
    ${'$'}("#enus").attr("href",pageUrl + "?l=en_US")
</script>
</th:block>
</body>
</html>
"""
    var codeIndexHtml = """<!doctype html>
<html lang="en" class="no-js" xmlns:th="http://www.thymeleaf.org">
<!-- /* ::meta, ::title, ::link, ::style, ::script */ -->
<head th:replace="fragment :: common_head(~{::meta},~{::title},~{::link},~{},~{})">
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>首页</title>
    <!--tag::引入 css, js[]-->
    <link rel="stylesheet"
          th:href="@{/webjars/html5-boilerplate/${bpVersion}/dist/css/normalize.css}"
          href="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/css/normalize.css">
    <link th:href="@{/webjars/font-awesome/${faVersion}/web-fonts-with-css/css/fontawesome-all.min.css}" rel="stylesheet" href="https://use.fontawesome.com/releases/v${faVersion}/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">
    <link th:href="@{/webjars/bootstrap/${bootstrapVersion}/css/bootstrap.min.css}" href="https://cdn.bootcss.com/bootstrap/${bootstrapVersion}/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet"
          th:href="@{/webjars/html5-boilerplate/${bpVersion}/dist/css/main.css}"
          href="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/css/main.css">
    <!--这里加入 app.css -->
    <link rel="stylesheet"  th:href="@{/assets/css/app.css}"
          href="../static/assets/css/app.css">
    <!--end::引入 css, js[]-->
</head>
<body>
<!-- fragment 是 thymeleaf 视图解析器识别的视图名 -->
<th:block th:replace="fragment :: browser"></th:block>
<header id="header" th:replace="fragment :: header"></header>
<div class="container">
    <div class="row">
        <div class="col-md-2 bg-info">
            country: <span th:text="${'$'}{#locale.country}"></span>
        </div>
        <div class="col-md-2">
            <p th:utext="#{index.welcome}">欢迎语</p>
        </div>

        <div class="col-md bg-secondary">
            <p>If you click on me, I will disappear.</p>
        </div>
    </div>
    <hr>
    <div class="row">
        <div class="col-md-8 bg-info">
            <a href="" class="btn btn-primary" th:href="@{/thymeleaf/demo}">Thymeleaf 演示</a>
        </div>
        <div class="col-md-4 bg-secondary">other content</div>
    </div>
</div>
<footer id="footer" th:replace="fragment :: footer"></footer>
<script th:src="@{/webjars/html5-boilerplate/${bpVersion}/dist/js/vendor/modernizr-${modernizrVersion}.min.js}"
        src="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/js/vendor/modernizr-${modernizrVersion}.min.js"></script>
<script th:src="@{/webjars/jquery/${jqueryVersion}/jquery.js}"
        src="//cdn.jsdelivr.net/webjars/org.webjars/jquery/${jqueryVersion}/jquery.js"></script>
<script th:src="@{/webjars/html5-boilerplate/${bpVersion}/dist/js/plugins.js}"
        src="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/js/plugins.js"></script>
<script th:src="@{/webjars/bootstrap/${bootstrapVersion}/js/bootstrap.bundle.min.js}"
        src="https://cdn.bootcss.com/bootstrap/${bootstrapVersion}/js/bootstrap.bundle.js"></script>
<th:block th:replace="fragment :: scriptlib"></th:block>
<!--这里导入自己的 js 文件-->
<script th:src="@{/assets/js/app.js}"
        src="../static/assets/js/app.js"></script>
<script type="text/javascript">
    ${'$'}(function() {
        ${'$'}("p").click(function(){
            ${'$'}(this).hide()
        })
    })
</script>
</body>
</html>
"""
    // templates/thymeleaf/demo.html
    var thymeleafDir = "$templatesDir/thymeleaf"
    var thymeleafDemoHtml = "demo.html"
    var codeThymeleafDemoHtml = """<!doctype html>
<html lang="en" class="no-js" xmlns:th="http://www.thymeleaf.org">
<!-- /* ::meta, ::title, ::link, ::style, ::script */ -->
<head th:replace="fragment :: common_head(~{::meta},~{::title},~{::link},~{},~{})">
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Thymeleaf Demo</title>
    <!--tag::引入 css, js[]-->
    <link rel="stylesheet"
          th:href="@{/webjars/html5-boilerplate/${bpVersion}/dist/css/normalize.css}"
          href="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/css/normalize.css">
    <link th:href="@{/webjars/font-awesome/${faVersion}/web-fonts-with-css/css/fontawesome-all.min.css}" rel="stylesheet" href="https://use.fontawesome.com/releases/v${faVersion}/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">
    <link th:href="@{/webjars/bootstrap/${bootstrapVersion}/css/bootstrap.min.css}" href="https://cdn.bootcss.com/bootstrap/${bootstrapVersion}/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet"
          th:href="@{/webjars/html5-boilerplate/${bpVersion}/dist/css/main.css}"
          href="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/css/main.css">
    <!--这里加入 app.css -->
    <link rel="stylesheet"  th:href="@{/assets/css/app.css}"
          href="../../static/assets/css/app.css">
    <!--end::引入 css, js[]-->
</head>
<body>
<th:block th:replace="fragment :: browser"></th:block>
<header id="header" th:replace="fragment :: header"></header>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <p th:text="TODO">Todo</p>
        </div>
    </div>
</div>
<footer id="footer" th:replace="fragment :: footer"></footer>
<script th:src="@{/webjars/html5-boilerplate/${bpVersion}/dist/js/vendor/modernizr-${modernizrVersion}.min.js}"
        src="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/js/vendor/modernizr-${modernizrVersion}.min.js"></script>
<script th:src="@{/webjars/jquery/${jqueryVersion}/jquery.js}"
        src="//cdn.jsdelivr.net/webjars/org.webjars/jquery/${jqueryVersion}/jquery.js"></script>
<script th:src="@{/webjars/html5-boilerplate/${bpVersion}/dist/js/plugins.js}"
        src="//cdn.jsdelivr.net/webjars/org.webjars.npm/html5-boilerplate/${bpVersion}/dist/js/plugins.js"></script>
<script th:src="@{/webjars/bootstrap/${bootstrapVersion}/js/bootstrap.bundle.min.js}"
        src="https://cdn.bootcss.com/bootstrap/${bootstrapVersion}/js/bootstrap.bundle.js"></script>
<th:block th:replace="fragment :: scriptlib"></th:block>
<!--这里导入自己的 js 文件-->
<script th:src="@{/assets/js/app.js}"
        src="../../static/assets/js/app.js"></script>
<script type="text/javascript">
    // 这里写当前页的 js
</script>
</body>
</html>
"""
    // cn.codergege.demo.controller.ThymeleafController
    var thymeleafControllerFileName = "ThymeleafController.kt"
    var codeThymeleafController = """package $packageName.controller

import $packageName.dao.PersonRepository
import $packageName.service.PersonService
import $packageName.utils.toDate
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping

@RequestMapping("/thymeleaf")
@Controller
class ThymeleafController {
    @Autowired
    lateinit var personService: PersonService
    @Autowired
    lateinit var personRepository: PersonRepository

    @RequestMapping("/demo")
    fun demoPage(map: MutableMap<String, Any>): String {
        map["date"] = "1986-05-29".toDate()
        val persons = personRepository.findAll()
        map["persons"] = persons
        return "/thymeleaf/demo"
    }
}
"""
    //cn.codergege.demo.config.MyLocaleResolver
    var myLocaleResolverFileName = "MyLocaleResolver.kt"
    var codeMyLocaleResolver = """package $packageName.config

import org.springframework.util.StringUtils
import org.springframework.web.servlet.LocaleResolver
import java.util.*
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class MyLocaleResolver: LocaleResolver {
    override fun resolveLocale(request: HttpServletRequest): Locale {
        var locale = Locale.getDefault()
        val l = request.getParameter("l")
        if(!StringUtils.isEmpty(l)) {
            val ls = l.split("_")
            locale = Locale(ls[0], ls[1])
        }
        return locale
    }
    override fun setLocale(request: HttpServletRequest, response: HttpServletResponse?, locale: Locale?) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}
"""
    //cn.codergege.demo.config.WebConfig
    var webConfigFileName = "WebConfig.kt"
    var codeWebConfig = """package $packageName.config

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.LocaleResolver
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

/**
 * 不要加 @EnableWebMvc 注解, 一旦加了这个注解, 就完全由自己掌控 webmvc 的配置了.
 * Spring boot 的自动配置都会失效.
 * @author Codergege
 */
//@EnableWebMvc
@Configuration
class WebConfig: WebMvcConfigurer {

	/**
	 * 因为 spring boot 默认首页没有包含 templates 文件夹下的 index.html,
	 * 而 thymeleaf 的 html 文件必须放在 templates 文件夹下, 所以这里做一下映射.
	 */

	override fun addViewControllers(registry: ViewControllerRegistry) {
		registry.addViewController("/").setViewName("index")
		registry.addViewController("/index.html").setViewName("index")
	}

	@Bean
	fun localeResolver(): LocaleResolver {
		return MyLocaleResolver()
	}

	// 在 spring boot 中, ResourceBundleMessageSource 不需要自己配置了.
}
"""
    // cn.codergege.demo.config.conversion.DateFormatter
    var conversionPackageDir = "$configPackageDir/conversion"
    var dateFormatterFileName = "DateFormatter.kt"
    var codeDateFormatter = """package $packageName.config.conversion

import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.MessageSource
import org.springframework.format.Formatter
import org.springframework.stereotype.Component

@Component
class DateFormatter: Formatter<Date> {
    private val log = LoggerFactory.getLogger(javaClass)

    @Autowired
    lateinit var messageSource: MessageSource

    @Throws(ParseException::class)
    override fun parse(text: String, locale: Locale): Date {
        val sdf = createDateFormat(locale)
        return sdf.parse(text)
    }

    override fun print(date: Date, locale: Locale): String {
        val sdf = createDateFormat(locale)
        return sdf.format(date)
    }

    private fun createDateFormat(local: Locale): SimpleDateFormat {
        // 1) 根据 页面的 local 去 messages_zh_CN.properties 或 messages_en_US.properties 中去找
        // 2) 没找到对应的 key, 就去 messages.properties 中找
        // 3) 还没找到, 就用 yyyy-MM-dd 这个默认值
        val format = messageSource.getMessage("date.format", null, "yyyy-MM-dd", local)
        val sdf = SimpleDateFormat(format)
        log.info("----> Fomatter runs... local is {}", local.country)
        return sdf
    }
}
"""
}
